<?php

/**
 * ********************************************
 * Description   : 微信支付和银联支付接口
 * Filename      : pay.php
 * Create time   : 2014-10-28 15:34:24
 * Last modified : 2016-04-22 12:00:00
 * License       : MIT, GPL
 * ********************************************
 */
require_once "weixin/WxPay.Api.php";

class mobileapi_rpc_pay extends mobileapi_frontpage {

    public function __construct($app) {
        parent::__construct($app);
        $this->app = app::get('b2c');
    }

    /**
     * 微信支付获取prepadid
     * 
     * @params payment_order_id 订单号（recharge可不填）
     * @params payment_cur_money 支付金额
     * @params payment_pay_app_id 支付方式ID编码（微信SDK支付为wxpaysdk）
     * @params pay_object 支付对象{order, recharge, joinfee}，不填时默认为order
     * 
     * @return  json : 支付宝预支付信息
     * 
     * @author updated by AlanPi <pijian@shopexunit.com> 2016.04.22
     */
    function weixinpay() {
        $sdf = $this->_dopayment();
        logger::notice('_dopayment返回值$sdf:'.var_export($sdf, 1));
        $data = array();

        if (null == $sdf) {
            return $data['error'] = '支付失败！';
        }
        if ($sdf['pay_app_id'] == 'wxallinpaysdk') {
            $data = $sdf['wxdata'];
        }else{
            $appId = $this->_getConf('appId', 'weixin_payment_plugin_wxpaysdk');
            $Mchid = $this->_getConf('Mchid', 'weixin_payment_plugin_wxpaysdk');
            $Key = $this->_getConf('Key', 'weixin_payment_plugin_wxpaysdk');

            $payment_id = $sdf['payment_id'];
            if (!$payment_id) {
                return $data['error'] = '支付单号为空！';
            }

            $bill = app::get('ectools')->model('order_bills')->getRow('*', array('bill_id' => $payment_id));
            if (!$bill) {
                return $data['error'] = '该支付单不存在！';
            }

            // 付款金额
            $total = ceil($bill['money'] * 100);

            // 支付标题
            $body = '预存款充值';
            if ('order' == $bill['pay_object']) {
                $body = $this->_get_body($bill['rel_id']);
            }

            // 统一下单
            $input = new WxPayUnifiedOrder();
            $input->SetOut_trade_no($payment_id);
            $input->SetTrade_type("APP");
            $input->SetBody($body);
            $input->SetTotal_fee($total);

            // 微信预支付信息
            $order = WxPayApi::unifiedOrder($input);
            if ($order['return_msg'] == 'OK' && $order['result_code'] == 'SUCCESS' && $order['return_code'] == 'SUCCESS') {
                $data['prepayid'] = $order['prepay_id'];
                $data['pay_sign'] = $order['sign'];
                $data['nonce_str'] = $order['nonce_str'];
                $data['timestamp'] = time();
                $data['appid'] = $appId;
                $data['partnerid'] = $Mchid;
                $data['package'] = 'Sign=WXPay';
                $data['api_key'] = $Key;
                // 增加主动回调参数，payment_id
                $data['payment_id'] = $payment_id;
            } else {
                $data['error'] = $order['err_code_des'];
            }
        }
        logger::notice('微信预支付信息2$data:'.var_export($data, 1));
        return $data;
    }

    /**
     * 得到配置参数
     * 
     * @params string key
     * 
     * @payment api interface class name
     * 
     * @author AlanPi <pijian@shopexunit.com>
     */
    private function _getConf($key, $pkey) {
        $val = app::get('ectools')->getConf($pkey);
        $val = unserialize($val);

        return $val['setting'][$key];
    }

    /**
     * 获取支付标题信息
     * 
     * @param int $order_id
     * 
     * @return string 标题信息
     * 
     * @author AlanPi <pijian@shopexunit.com>
     */
    private function _get_body($order_id = null) {
        $orderItem = app::get('b2c')->model('order_items')->getRow('*', array('order_id' => $order_id));

        return $orderItem['name'];
    }

    /**
     * 提交支付
     * 
     * @return array 支付单信息
     * 
     * @author AlanPi <pijian@shopexunit.com>
     */
    private function _dopayment() {
        $pay_object = empty($_POST['pay_object']) ? 'order' : $_POST['pay_object'];
        $combination_pay = false;


        $payment['order_id'] = trim($_POST['payment_order_id']);
        $payment['def_pay']['cur_money'] = trim($_POST['payment_cur_money']);
        $payment['def_pay']['pay_app_id'] = trim($_POST['payment_pay_app_id']);
        $payment['memo'] = trim($_POST['payment_memo']);

        unset($_POST);

        $_POST['payment'] = $payment;

        if ($pay_object) {
            $member_id = kernel::single('b2c_user_object')->get_member_id();
            $objOrders = app::get('b2c')->model('orders');
            $objPay = kernel::single('ectools_pay');
            $objMath = kernel::single('ectools_math');
            // 得到商店名称
            $shopName = app::get('site')->getConf('site.name');
            // Post payment information.
            $sdf = $_POST['payment'];
            unset($sdf['def_pay']);
            unset($sdf['other_online']);
            if ($combination_pay == true) {
                if ($_POST['payment']['other_online']) {
                    $sdf['pay_app_id'] = $_POST['payment']['other_online']['pay_app_id'];
                    $sdf['cur_money'] = $_POST['payment']['other_online']['cur_money'] ? $_POST['payment']['other_online']['cur_money'] : 0;
                }
            } else {
                if ($_POST['payment']['def_pay']) {
                    $sdf['pay_app_id'] = $_POST['payment']['def_pay']['pay_app_id'];
                    $sdf['cur_money'] = $_POST['payment']['def_pay']['cur_money'] ? $_POST['payment']['def_pay']['cur_money'] : 0;
                }
            }

            if ($member_id)
                $sdf['member_id'] = $member_id;

            if (!$sdf['pay_app_id']) {
                kernel::single('base_rpc_service')->send_user_error('pay_app_id_null', '支付方式不能为空!');
            }

            $payment_cfgs = app::get('ectools')->model('payment_cfgs');
            if (!$payment_cfgs->check_payment_open($sdf['pay_app_id'])) {
                kernel::single('base_rpc_service')->send_user_error('pay_app_id_error', '不支持此支付方式!');
            }

            $order_items = app::get('b2c')->model('order_items')->getList('name', array('order_id' => $sdf['order_id']), 0, 1);

            $sdf['body'] = $order_items[0]['name'];
            $sdf['pay_object'] = $pay_object;
            $sdf['shopName'] = $shopName;
            switch ($sdf['pay_object']) {
                case 'order':
                    $orderMemberId = app::get('b2c')->model('orders')->getList('member_id', array('order_id' => $sdf['order_id']));
                    if (!$orderMemberId[0]['member_id'] || $orderMemberId[0]['member_id'] != $member_id) {
                        kernel::single('base_rpc_service')->send_user_error('order_id_error', '无效订单，不能支付');
                    }
                    $arrOrders = $objOrders->dump($sdf['order_id'], '*');
                    if ($arrOrders['payinfo']['pay_app_id'] != $sdf['pay_app_id']) {
                        $class_name = "";
                        $obj_app_plugins = kernel::servicelist("ectools_payment.ectools_mdl_payment_cfgs");
                        foreach ($obj_app_plugins as $obj_app) {
                            $app_class_name = get_class($obj_app);
                            $arr_class_name = explode('_', $app_class_name);
                            if (isset($arr_class_name[count($arr_class_name) - 1]) && $arr_class_name[count($arr_class_name) - 1]) {
                                if ($arr_class_name[count($arr_class_name) - 1] == $sdf['pay_app_id']) {
                                    $pay_app_ins = $obj_app;
                                    $class_name = $app_class_name;
                                }
                            } else {
                                if ($app_class_name == $sdf['pay_app_id']) {
                                    $pay_app_ins = $obj_app;
                                    $class_name = $app_class_name;
                                }
                            }
                        }
                        $strPaymnet = app::get('ectools')->getConf($class_name);
                        $arrPayment = unserialize($strPaymnet);

                        $sdf['cur_money'] = $objMath->number_multiple(array($sdf['cur_money'], $arrOrders['cur_rate']));
                        $cost_payment = $objMath->number_multiple(array($objMath->number_minus(array($objMath->number_minus(array($arrOrders['total_amount'], $arrOrders['payinfo']['cost_payment'])), $arrOrders['payed'])), $arrPayment['setting']['pay_fee']));
                        $total_amount = $objMath->number_plus(array($objMath->number_minus(array($arrOrders['total_amount'], $arrOrders['payinfo']['cost_payment'])), $cost_payment));
                        $cur_money = $objMath->number_multiple(array($total_amount, $arrOrders['cur_rate']));

                        // 更新订单支付信息
                        $arr_updates = array(
                            'order_id' => $sdf['order_id'],
                            'payinfo' => array(
                                'pay_app_id' => $sdf['pay_app_id'],
                                'cost_payment' => $objMath->number_multiple(array($cost_payment, $arrOrders['cur_rate'])),
                            ),
                            'currency' => $arrOrders['currency'],
                            'cur_rate' => $arrOrders['cur_rate'],
                            'total_amount' => $total_amount,
                            'cur_amount' => $cur_money,
                        );

                        $changepayment_services = kernel::servicelist('b2c_order.changepayment');
                        foreach ($changepayment_services as $changepayment_service) {
                            $changepayment_service->generate($arr_updates);
                        }

                        $objOrders->save($arr_updates);

                        $arrOrders = $objOrders->dump($sdf['order_id'], '*');
                        /** 需要想中心发送支付方式修改的动作 * */
                        $obj_b2c_pay = kernel::single('b2c_order_pay');
                        $obj_b2c_pay->order_payment_change($arrOrders);
                    }

                    //ajx 防止恶意修改支付金额，导致支付状态异常
                    if ($pay_object == 'order' && (!isset($_POST['payment']['other_online']) || $combination_pay == true)) {
                        $orders = $objOrders->dump($sdf['order_id']);
                        $sdf['cur_amount'] = $objMath->number_minus(array($orders['cur_amount'], $orders['payed']));
                        $orders['total_amount'] = $objMath->number_div(array($orders['cur_amount'], $orders['cur_rate']));
                        $sdf['money'] = floatval($orders['total_amount'] - $orders['payed']);
                        $sdf['currency'] = $orders['currency'];
                        $sdf['cur_money'] = $objMath->number_minus(array($orders['cur_amount'], $orders['payed']));
                        $sdf['cur_rate'] = $orders['cur_rate'];
                    }

                    // 检查是否能够支付
                    $obj_checkorder = kernel::service('b2c_order_apps', array('content_path' => 'b2c_order_checkorder'));
                    $sdf_post = $sdf;
                    $sdf_post['money'] = $sdf['cur_money'];
                    if (!$obj_checkorder->check_order_pay($sdf['order_id'], $sdf_post, $message)) {
                        //$this->result($arrOrders,$message);
                        return $this->result($arrOrders, $message);
                    }

                    if ($sdf['pay_app_id'] == 'offline') {
                        return $this->result_pay($arrOrders['order_id'], true);
                    }

                    if ($sdf['pay_app_id'] == 'offlinecard') {
                        return $this->result_pay($arrOrders['order_id'], true);
                    }

                    if (!$sdf['pay_app_id'])
                        $sdf['pay_app_id'] = $arrOrders['payinfo']['pay_app_id'];

                    $sdf['currency'] = $arrOrders['currency'];
                    $sdf['total_amount'] = $arrOrders['total_amount'];
                    $sdf['payed'] = $arrOrders['payed'] ? $arrOrders['payed'] : '0.000';
                    $sdf['money'] = $objMath->number_div(array($sdf['cur_money'], $arrOrders['cur_rate']));

                    $sdf['payinfo']['cost_payment'] = $arrOrders['payinfo']['cost_payment'];

                    // 相关联的id.
                    $sdf['rel_id'] = $sdf['order_id'];
                    break;
                case 'recharge':
                    $sdf['money'] = $sdf['cur_money'];
                    // 得到充值信息
                    $sdf['rel_id'] = $sdf['member_id'];
                    break;
                case 'joinfee':
                    // 得到加盟费信息
                    break;
                default:
                    // 其他的卡充值
                    $sdf['rel_id'] = $sdf['rel_id'];
                    break;
            }

            $sdf['payment_id'] = $objPay->get_payment_id($sdf['rel_id']);

            $sdf['status'] = 'ready';
            // 需要加入service给其他实体和虚拟卡
            $obj_prepaid = kernel::service('b2c.prepaidcards.add');
            $is_save_prepaid = false;
            if ($obj_prepaid) {
                $is_save_prepaid = $obj_prepaid->gen_charge_log($sdf);
            }

            if ($_POST['payment']['def_pay']['pay_app_id'] === 'wxpayjsapi') {
                $sdf['pay_app_type'] = 'mobile';
            }
            if ($_POST['payment']['def_pay']['pay_app_id'] === 'malipay') {
                $sdf['pay_app_type'] = 'mobile';
            }

            $is_payed = $objPay->generate($sdf, $this, $msg);

            if ($is_payed) {
                $sdf['wxdata'] = $is_payed;
                return $sdf;
            }

            return null;
        }
    }

}
